/**
 * FtpExplorer.java
 * @author: liuex
 * 2007-12-24 ����10:35:55
 *
 * note: 
 */
package org.lex.ftp.ui.explorer;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import org.lex.catalog.CatalogEvent;
import org.lex.catalog.CatalogListener;
import org.lex.explorer.StatusBar;
import org.lex.explorer.ToggleSplitPaneAction;
import org.lex.ftp.FTP;
import org.lex.ftp.model.FTPModel;
import org.lex.ftp.model.NullFTPModel;
import org.lex.ftp.net.FTPUtils;
import org.lex.ftp.ui.explorer.directory.FTPDirectoryExplorer;
import org.lex.ftp.ui.explorer.file.FTPFileExplorer;
import org.lex.ftp.util.Resources;
import org.lex.net.ftp.FTPURL;
import org.lex.net.ftp.IFTPClient;
import org.lex.net.ftp.IFTPFile;
import org.lex.swing.ContainerFactory;
import org.lex.swing.Swings;
import org.lex.swing.table.TableHelper;
import org.lex.utils.Pair;
import org.lex.utils.text.SizeFormat;


public class FTPExplorer extends JPanel implements CatalogListener {
	public final FTP app;
	// -----------------------
	private JSplitPane splitPane;
	private JToolBar toolBar;
	private JButton upButton;
	private JButton refreshButton;
	private JToggleButton treeButton;
	private AddressBar addressBar;
	// =============================
	private FTPDirectoryExplorer directoryExplorer = null;
	private FTPFileExplorer fileExplorer = null;
	private StatusBar statusBar;
	// ------------------------------
	private FTPModel ftpModel = NullFTPModel.getInstance();

	public static void main(String[] args) {
		Swings.setUseBoldMetalFont(false);
		FTPExplorer e = new FTPExplorer(null);
		Swings.show(e, false);
		FTPURL url = new FTPURL("10.85.25.200");
		e.open(url);
	}

	public FTPExplorer(FTP app) {
		super();
		this.app = app;
		this.initialize();
		this.hookActionListeners();
	}

	public void catalogChanged(CatalogEvent e) {
		this.updateStatusBar(ftpModel.list());
	}

	public FTPModel getFTPModel() {
		return ftpModel;
	}

	public void setFTPModel(FTPModel model) {
		this.ftpModel.removeCatalogListener(this);
		this.ftpModel = model;
		this.ftpModel.addCatalogListener(this);
		// ---------------------------------------
		this.getAddressBar().setFTPModel(model);
		this.getDirectoryExplorer().setFTPModel(model);
		this.getFileExplorer().setFTPModel(model);
	}

	/*
	 * connections-related methods
	 */
	public void open(FTPURL url) {
		FTPExplorerUtils.open(this, url);
	}

	public void close() {
		FTPExplorerUtils.close(this);
	}

	public boolean isConnected() {
		IFTPClient c = this.getFTPClient();
		return null == c ? false : c.isServerOpen();
	}

	public IFTPClient getFTPClient() {
		return this.ftpModel.getFTPClient();
	}

	public FTPDirectoryExplorer getDirectoryExplorer() {
		if (null == directoryExplorer)
			this.directoryExplorer = new FTPDirectoryExplorer();
		return directoryExplorer;
	}

	public FTPFileExplorer getFileExplorer() {
		if (null == fileExplorer)
			fileExplorer = new FTPFileExplorer();
		return fileExplorer;
	}

	private void updateStatusBar(IFTPFile[] files) {
		Pair<String, String> p = FTPUtils.generateFileStatistics(files);
		this.getStatusBar().setInformation(p.first());
		this.getStatusBar().setSize(p.second());
	}

	private void hookActionListeners() {
		// toolbar
		this.getUpButton().addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				ftpModel.cdUp();
			}
		});
		this.getRefreshButton().addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				ftpModel.reload();
			}
		});
		// table popup-menu
		JTable table = this.getFileExplorer();
		table.setComponentPopupMenu(new TablePopupMenu(this));
		// table selection-listener
		table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e) {
				IFTPFile[] files = fileExplorer.getSelectedFiles();
				if (null == files)
					return;
				Pair<Integer, Long> p = FTPUtils.getFileStatistics(files);
				StringBuilder buf = new StringBuilder();
				buf.append(files.length).append(" objects selected ( ");
				buf.append(p.first()).append(" files, ");
				buf.append(files.length - p.first()).append(" folders )");
				getStatusBar().setInformation(buf.toString());
				buf.setLength(0);
				buf.append(SizeFormat.autoFormat(p.second())).append('B');
				getStatusBar().setSize(buf.toString());
			}
		});
		// table auto-resize
		TableHelper.test(table);
	}

	private void initialize() {
		this.setLayout(new BorderLayout());
		this.add(getToolBar(), BorderLayout.NORTH);
		this.add(getSplitPane(), BorderLayout.CENTER);
		this.add(getStatusBar(), BorderLayout.SOUTH);
	}

	private JToolBar getToolBar() {
		if (toolBar == null) {
			toolBar = new JToolBar();
			toolBar.add(getTreeButton());
			toolBar.add(getUpButton());
			toolBar.add(getRefreshButton());
			toolBar.addSeparator();
			toolBar.add(this.getAddressBar());
		}
		return toolBar;
	}

	private JToggleButton getTreeButton() {
		if (treeButton == null) {
			treeButton = new JToggleButton(new ToggleSplitPaneAction(getSplitPane()));
		}
		return treeButton;
	}

	private JButton getUpButton() {
		if (upButton == null) {
			upButton = new JButton();
			upButton.setToolTipText("Go Up");
			upButton.setIcon(Resources.getIcon(Resources.GoUpIcon));
		}
		return upButton;
	}

	private AddressBar getAddressBar() {
		if (null == addressBar)
			addressBar = new AddressBar();
		return addressBar;
	}

	private JButton getRefreshButton() {
		if (refreshButton == null) {
			refreshButton = new JButton();
			refreshButton.setToolTipText("Refresh");
			refreshButton.setIcon(Resources.getIcon(Resources.RefreshIcon));
		}
		return refreshButton;
	}

	private JSplitPane getSplitPane() {
		if (splitPane == null) {
			splitPane = ContainerFactory.createBorderlessSplitPane();
			splitPane.setName(getClass().getName() + ".splitPane");
			splitPane.setResizeWeight(0.4);
			splitPane.setDividerSize(5);
			splitPane.add(new JScrollPane(this.getDirectoryExplorer()), JSplitPane.LEFT);
			splitPane.add(new JScrollPane(this.getFileExplorer()), JSplitPane.RIGHT);
		}
		return splitPane;
	}

	private StatusBar getStatusBar() {
		if (null == statusBar)
			statusBar = new StatusBar();
		return statusBar;
	}
}
